#include "bhxjglspeedometer.h"

BHXJGLSpeedometer::BHXJGLSpeedometer():BHXJGLModel()
{

}
BHXJGLSpeedometer::~BHXJGLSpeedometer()
{
    delete ttf;
    for(BHXJGLShader* s :shaders)
    {
        delete s;
    }
}

///
void BHXJGLSpeedometer::Init(BHXJGLFUN *arg)
{
    this->gl=arg;
    //shader
    {
        BHXJGLShader* shader=new BHXJGLShader();
        shader->Init(arg,":/Speedometer/speedometervertex0.vert",":/Speedometer/speedometerfragment2.frag",":/Speedometer/speedometergeometry.geom");
        this->shaders.push_back(shader);

        BHXJGLShader* shader1=new BHXJGLShader();
        shader1->Init(arg,":/Speedometer/speedometervertex0.vert",":/Speedometer/speedometerfragment1.frag",":/Speedometer/speedometergeometry.geom");
        this->shaders.push_back(shader1);
    }

    //字体
    ttf=new  BHXJGLTTF();
    ttf->Init(gl,"./font/DejaVuSansMono/DejaVuSansMono-1.ttf");

    unsigned int circlesegnum=128;
    unsigned int arcnum=4;
    float radias=0.96f;
    auto cps=BHXJGLModelHelper::getCirclePoints(circlesegnum);
    auto aps=BHXJGLModelHelper::getArcPoints(arcnum,90.f);
    auto qps=BHXJGLModelHelper::getQuadPoints();
    glm::mat3 mat3;

    //底盘
    {
        BHXJGLMesh *mbase=new BHXJGLMesh();
        BHXJGLVertex v;
        v.position=glm::vec3(0);
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(0.5);
        mbase->vertices.push_back(v);


        //平底
        for(unsigned int i=0;i<cps->size();++i)
        {
            //顶点
            v.position=cps->at(i)*radias;
            v.texcoodr=glm::vec2(v.position.x/2+0.5f,v.position.y/2+0.5f);
            v.normal=glm::vec3(0,0,1);
            mbase->vertices.push_back(v);
        }

        //锅壁
        for(unsigned int a=1;a<aps->size();++a)
        {
            for(unsigned int c=0;c<cps->size();++c)
            {
                //顶点
                //v.position=cps->at(c)*(aps->at(a).x*(1-radias)/2+radias);
                v.position=cps->at(c)*(aps->at(a).x*(1-radias)+radias);
                v.position.z=(1-radias)/2*(aps->at(a).y-1);

                mat3[0]=glm::vec3(cps->at(c).y,-cps->at(c).x,0);
                mat3[1]=glm::vec3(cps->at(c).x,cps->at(c).y,0);
                mat3[2]=glm::vec3(0,0,1);
                v.normal=glm::vec3(0,aps->at(a).x,aps->at(a).y*2);
                v.normal=glm::normalize(mat3*v.normal);

                v.texcoodr=glm::vec2(v.position.x/2+0.5f,v.position.y/2+0.5f);
                mbase->vertices.push_back(v);
            }
        }

        BHXJGLModelHelper::addPieToMesh(mbase,0,1,circlesegnum,BHXJFront);

        for(unsigned int i=0;i<arcnum;++i)
        {
            BHXJGLModelHelper::addStripeToMesh(mbase,i*cps->size()+1,(i+1)*cps->size()+1,circlesegnum);
        }


        //加入网格并初始化
        this->meshes.push_back(mbase);
        mbase->Init(this->gl);
        //mbase->textures.push_back(texture);
    }

    //盖子
    {
        BHXJGLMesh *mtop=new BHXJGLMesh();
        BHXJGLVertex v;
        v.position=glm::vec3(0);
        v.position.z+=0.2f;
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(0.5);
        mtop->vertices.push_back(v);

        float radiastop=radias*0.5f;
        for(unsigned int i=0;i<cps->size();++i)
        {
            v.position=cps->at(i)*radiastop;
            v.position.z+=0.2f;
            v.normal=glm::vec3(0,0,1);
            v.texcoodr=glm::vec2(v.position.x/2+0.5f,v.position.y/2+0.5f);
            mtop->vertices.push_back(v);
        }

        for(unsigned int a=1;a<aps->size();++a)
        {
            for(unsigned int c=0;c<cps->size();++c)
            {
                //顶点
                v.position=cps->at(c)*(aps->at(a).x*(0.5f-radiastop)*2+radiastop);
                v.position.z=(0.5f-radiastop)*(aps->at(a).y-1);
                v.position.z+=0.2f;

                mat3[0]=glm::vec3(cps->at(c).y,-cps->at(c).x,0);
                mat3[1]=glm::vec3(cps->at(c).x,cps->at(c).y,0);
                mat3[2]=glm::vec3(0,0,1);

                v.normal=glm::vec3(0,aps->at(a).x,aps->at(a).y*2);
                v.normal=glm::normalize(mat3*v.normal);

                v.texcoodr=glm::vec2(v.position.x/2+0.5f,v.position.y/2+0.5f);
                mtop->vertices.push_back(v);
            }
        }
        BHXJGLModelHelper::addPieToMesh(mtop,0,1,circlesegnum,BHXJFront);

        for(unsigned int i=0;i<arcnum;++i)
        {
            BHXJGLModelHelper::addStripeToMesh(mtop,i*cps->size()+1,(i+1)*cps->size()+1,circlesegnum);
        }

        //加入网格并初始化
        this->meshes.push_back(mtop);
        mtop->Init(this->gl);
    }

    //刻度
    {
        BHXJGLMesh *mscale=new BHXJGLMesh();
        BHXJGLVertex v;

        float scalewidth=0.005f;
        float scalelen=0.12f;
        float radiassssacle=0.75f-scalelen/2;

        for(unsigned int i=0;i<53;++i)
        {
            if(i%4!=0)
                scalelen=0.06f;
            else
                scalelen=0.12f;
            radiassssacle=0.75f-scalelen/2;

            float a=glm::radians(-180.f+i*5);
            float sa=glm::sin(a);
            float ca=glm::cos(a);

            glm::mat3 mat;
            mat[0]=glm::vec3(ca,-sa,0)*scalewidth;
            mat[1]=glm::vec3(sa,ca,0)*(scalelen/2);
            mat[2]=glm::vec3(0,0,1);

            for(unsigned int q=0;q<4;++q)
            {
                v.position=mat*qps->at(q);
                v.position=v.position+glm::vec3(sa*radiassssacle,ca*radiassssacle,0);
                v.normal=glm::vec3(0,0,1);
                v.texcoodr=glm::vec2(qps->at(q).x/2+0.5f,qps->at(q).y/2+0.5f);
                mscale->vertices.push_back(v);
            }

            BHXJGLModelHelper::addQuadToMesh(mscale,i*4);
        }

        this->meshes.push_back(mscale);
        mscale->Init(this->gl);
    }

    //指针
    {
        float pr=0.96f;
        float px=0.005f;
        float pz=0.f;
        BHXJGLMesh *mpointer=new BHXJGLMesh();
        BHXJGLVertex v;
        v.position=glm::vec3(px,pr,pz);
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(px,pr);
        mpointer->vertices.push_back(v);

        v.position=glm::vec3(px,0,pz);
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(px,0);
        mpointer->vertices.push_back(v);

        v.position=glm::vec3(-px,0,pz);
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(-px,0);
        mpointer->vertices.push_back(v);

        v.position=glm::vec3(-px,pr,pz);
        v.normal=glm::vec3(0,0,1);
        v.texcoodr=glm::vec2(-px,pr);
        mpointer->vertices.push_back(v);

        {
            mpointer->indices.push_back(0);
            mpointer->indices.push_back(2);
            mpointer->indices.push_back(1);


            mpointer->indices.push_back(0);
            mpointer->indices.push_back(3);
            mpointer->indices.push_back(2);
            mpointer->trianglescount+=2;
        }

        this->meshes.push_back(mpointer);
        mpointer->Init(this->gl);
    }
}

void BHXJGLSpeedometer::Paint(const BHXJGLPaintParam &p)
{
    gl->glEnable(GL_CULL_FACE);
    gl->glCullFace(GL_BACK);
    gl->glFrontFace(GL_CCW);

    glm::mat4 mat=glm::rotate(p.Model(),glm::radians(-180.f+_Speed),glm::vec3(0,0,-1));
    //盖子底盘
    {
        shaders[0]->use();
        glm::vec3 parallellightdir= glm::vec3( p.Model() *glm::vec4(0,0,-1,0));
        shaders[0]->setVec3("parallellight.direction",parallellightdir);
        shaders[0]->setVec3("parallellight.ambient",glm::vec3(0.1,0.1,0.1));
        shaders[0]->setVec3("parallellight.diffuse",glm::vec3(0.5,0.5,0.5));
        shaders[0]->setVec3("parallellight.specular",glm::vec3(0.5,0.5,0.5));
        shaders[0]->setVec3("viewPos",_viewPos);

        glm::vec4 p0=mat*glm::vec4(0,1.3f,0.1f,1);
        glm::vec4 p1=mat*glm::vec4(0,0.48f,0.1f,1);

        shaders[0]->setVec3("segmentlight.position0",glm::vec3(p0) );
        shaders[0]->setVec3("segmentlight.position1",glm::vec3(p1));
        shaders[0]->setVec3("segmentlight.ambient",glm::vec3(0.0f,0.1f,0.0f));
        shaders[0]->setVec3("segmentlight.diffuse",glm::vec3(0.0f,1.0f,0.0f));
        shaders[0]->setVec3("segmentlight.specular",glm::vec3(0.0f,1.0f,0.0f));

        shaders[0]->setMat4("projection",p.Projection());
        shaders[0]->setMat4("view",p.View());
        shaders[0]->setMat4("model",p.Model());
        shaders[0]->setVec3("material.ambient",glm::vec3(0.1,0.1,0.1));
        shaders[0]->setVec3("material.diffuse",glm::vec3(0.1,0.1,0.1));
        shaders[0]->setVec3("material.specular",glm::vec3(0.2,0.2,0.2));
        shaders[0]->setVec3("material.emission",glm::vec3(0,0,0));
        shaders[0]->setFloat("material.shininess",32.f);


        shaders[0]->setFloat("fan.midA",glm::radians(-180.f+_Speed*0.5f));
        shaders[0]->setFloat("fan.maxA",glm::radians(-180.f+_Speed));
        shaders[0]->setFloat("fan.edgA",glm::radians(3.0f));
        shaders[0]->setVec3("fan.Color",glm::vec3(1.0f,0.0f,0.f));

        shaders[0]->setBool("fan.show",true);
        meshes[0]->Paint(shaders[0]);
        shaders[0]->setBool("fan.show",false);
        meshes[1]->Paint(shaders[0]);
    }

    gl->glEnable(GL_POLYGON_OFFSET_FILL);
    gl->glPolygonOffset(-1.0f, -1.0f);

    //刻度
    shaders[0]->use();
    shaders[0]->setVec3("material.emission",glm::vec3(1.0,1.0,1.0));
    meshes[meshes.size()-2]->Paint(shaders[0]);

    gl->glPolygonOffset(-2.0f, -2.0f);
    //指针
    {
        shaders[1]->use();
        shaders[1]->setMat4("projection",p.Projection());
        shaders[1]->setMat4("view",p.View());
        shaders[1]->setMat4("model",mat);
        shaders[1]->setVec3("Color",glm::vec3(1.f,0.f,0.f));
        meshes[meshes.size()-1]->Paint(shaders[1]);
    }


    gl->glPolygonOffset(-1.0f, -1.0f);

    //刻度文字
    {
        for(int i=0;i<14;++i)
        {
            float r=glm::radians(i*20-180.f);
            float sinr=glm::sin(r);
            float cosr=glm::cos(r);
            glm::mat4 matttf=glm::translate(p.Model(),glm::vec3(sinr,cosr,0)*0.85f);//glm::rotate(p.Model(),glm::radians(-180.f+_Speed),glm::vec3(0,0,-1));

            matttf=glm::scale(matttf, glm::vec3(0.1f,0.1f,1.f));

            ttf->PaintString(QString::number(i*20),p.Projection(),p.View(),matttf,shaders[0]);
        }
    }
    //速度文字
    {
        glm::mat4 matttf=glm::translate(p.Model(),glm::vec3(0,0.05,0.2));
        matttf =glm::scale(matttf,glm::vec3(0.35f,0.4f,1.0f));
        ttf->PaintString(QString::number(static_cast<int>(_Speed)),p.Projection(),p.View(),matttf,shaders[0]);
        matttf=glm::translate(p.Model(),glm::vec3(0,-0.2,0.2));
        matttf =glm::scale(matttf,glm::vec3(0.16,0.12,1));

        glm::mat4 ma4{1};
        ma4[1]=glm::vec4(0.2,1,0,0);
        shaders[0]->use();
        shaders[0]->setVec3("material.emission",glm::vec3(0.6,0.0,0));
        ttf->PaintString("km/h",p.Projection(),p.View(),matttf*ma4,shaders[0]);
    }
    gl->glDisable(GL_POLYGON_OFFSET_FILL);

    gl->glDisable(GL_CULL_FACE);
}
